import type { Slots, VNode } from 'vue';
import { cloneVNode, isVNode } from 'vue';

interface UseChildrenOptions<T> {
    slots: Slots
    props: Record<string, any>
    sameType?: T
    transform?: (props: Record<string, any>, index: number) => Record<string, any>
}

// 深度规范化子节点
function normalizeChildNodes (children: any[], params?: Record<string, any>): VNode[] {
    return children.flatMap((child: any) => {
        // 处理函数类型子元素
        if (typeof child.type === 'symbol' && child.children) {
            return normalizeChildNodes(child.children, params);
        }
        // 处理数组嵌套
        if (Array.isArray(child)) {
            return normalizeChildNodes(child, params);
        }
        // 过滤非VNode元素
        return isVNode(child) ? [child] : [];
    });
}

function useChildren<T extends abstract new (...args: any) => any>({
    slots,
    props,
    sameType,
    transform
}: UseChildrenOptions<T>) {
    // 获取规范化后的子节点数组
    const children = slots.default?.() || [];
    const normalizedChildren = normalizeChildNodes(children);

    // 类型校验和过滤
    const validChildren = normalizedChildren.filter(child => {
        const isValid = !sameType || (child.type as any) === sameType;
        return isValid;
    });

    // 处理props合并
    const processedChildren = validChildren.map((child, index) => {
        let transferedProps = {};
        if (transform) {
            transferedProps = transform(child.props, index);
        }
        // 创建新的props对象
        const mergedProps = {
            ...child.props,
            ...props,
            // 自动注入索引值
            index,
            ...transferedProps
        };

        // 克隆并应用新props
        return cloneVNode(child, mergedProps);
    });

    return processedChildren;
}

export default useChildren;
